#include "AdminAccount.h"

AdminAccount::AdminAccount()
{
    //MemberAccount aMember;
}

AdminAccount::~AdminAccount()
{
    
}

AdminAccount::AdminAccount(void* a)
{
    this->memberID = (*(static_cast<AdminAccount*>(a))).memberID; ;
    this->memberName = (*(static_cast<AdminAccount*>(a))).memberName;
    this->memberPassword = (*(static_cast<AdminAccount*>(a))).memberPassword;
    this->reviewGrantedFor = (*(static_cast<AdminAccount*>(a))).reviewGrantedFor;
    this->reviewRequestedFor = (*(static_cast<AdminAccount*>(a))).reviewRequestedFor;		
    this->rewardsPoints = (*(static_cast<AdminAccount*>(a))).rewardsPoints;
    this->authenticate = (*(static_cast<AdminAccount*>(a))).authenticate;
    this->type = (*(static_cast<AdminAccount*>(a))).type;
}

void AdminAccount::createMemberAccount()
{

  bool exist;

	do{
    vector<MemberAccount*> create;
    vector<MemberAccount*> contain;
    vector<MemberAccount*>::iterator p;
    
    string temp;
    char confirm;
    MemberAccount* newMember = new MemberAccount;
    
    dbMemberAccount('s', create);
    cout<<endl<<endl;
    cout << "Enter Id :";
    getline(cin, temp);
    (*newMember).setMemberID(temp);
    cout << "Enter Name : ";
    getline(cin, temp);
    (*newMember).setMemberName(temp);
    cout << "Enter Password : ";
    getline(cin, temp);
    (*newMember).setRewardPoints(0);
    (*newMember).setType("Member");
    (*newMember).setAuthenticate(false);
    exist = false;
    cout<<"\n----------------------------------------\n";
    cout<<"MemberID:"<<(*newMember).getMemberID()<<endl;
    cout<<"Name:"<<(*newMember).getMemberName()<<endl;
    cout<<"Are u sure to add (y/n):";
    while(1){
        cin>>confirm;
				cin.clear();
				cin.ignore(100, '\n');				
        if(!(confirm == 'y' || confirm == 'n')){
            cout<<"Invalid input. Please re-enter:";
            continue;
						break;
        }
        break;
    }
    
    if(confirm == 'y')
		{
        p=create.begin();
        do{
            
            if((*p)->getMemberID() == (*newMember).getMemberID()){
                exist = true;
								break;
            }
            p++;
        }while(p!=create.end());
        
				if(exist)
					cout << "\nError! MemberID: " << (*newMember).getMemberID() << 
						"Name: " << (*p)->getMemberName() << " already exists!" << endl;
        else
				{
            contain.push_back(newMember);
            dbMemberAccount('i', contain);
        }
            
        cout<<"Going Back To Main..."<<endl<<endl;
    }
	}while(exist);
}

void AdminAccount::deleteMemberAccount(){
    
    
    vector<MemberAccount*> update;
    vector<MemberAccount*> contain;
    vector<MemberAccount*>::iterator q;
    int count=0, counter = 0;
    char confirm;
    
    dbMemberAccount('s', update);
    
    q=update.begin();
    while(q!=update.end()){
        cout<<"["<<count<<"]"<<(*q)->getMemberID()<<","<<(*q)->getMemberName()<<endl;
        count++;
        q++;
    }
    
    do{
        cout<<"Select Which to delete:";
        cin>>counter;
	cin.clear();
	cin.ignore(199, '\n');
        if (counter > count -1 || counter < 0)
        {
            cout << "Invalid Entry! Please try again" << endl;
        }
        
    } while (counter > count-1 || counter < 0);
            
    q=update.begin();
    q+=counter;
    
    cout<<"\n----------------------------------------\n";
    cout<< "Deleting Entry" << endl;
    cout<<"UserID:"<< (*q)->getMemberID()<<endl;
    cout<<"UserName:"<< (*q)->getMemberName()<<endl;
    cout<<"Are u sure (y/n):";
    while(1){
        cin>>confirm;
        if(!(confirm == 'y' || confirm == 'n')){
            cout<<"Invalid input. Please re-enter:";
            cin.clear();
            cin.ignore(100, '\n');
            continue;
        }
        break;
    }
    
    if(confirm == 'y'){
        contain.push_back(*q);
        dbMemberAccount('d', contain);
        cout << "Member Successfully Deleted" << endl;
    }
    
}

void AdminAccount::modifyMemberAccount()
{
    vector<MemberAccount*> toDB;
    vector<MemberAccount*> fromDB;
    vector<MemberAccount*>::iterator fromDBP, checkP;
		MemberAccount* maToDB = new MemberAccount;
    int count=0, counter = 0;
    char confirm;
    string temp;
    bool toconfirm;
    bool aunt, conflicts = false, modMID = false, inputError = false;
    
    dbMemberAccount('s', fromDB);
    
    fromDBP=fromDB.begin();
    while(fromDBP!=fromDB.end()){
        cout<<"["<<counter+1<<"]"<<(*fromDBP)->getMemberID()<<","<<(*fromDBP)->getMemberName()<<","<<(*fromDBP)->getRewardPoints()<<","<<(*fromDBP)->getType()<<endl;
        counter++;
        fromDBP++;
    }
    
     count =0;
    
        do
        {
            cout<<"Which one to modify? (0 to return):";
            cin >> count;  
            cin.clear();
            cin.ignore(100,'\n'); 
            if (count > counter || count < 0)
            {
                cout << "Invalid Parameter Please Try Again." << endl;
            }
 
        } while (count > counter || count < 0);
    
        if (count != 0)
        {
            fromDBP=fromDB.begin();
            fromDBP+=count-1;
    
            cout<<"UserID:"<<(*fromDBP)->getMemberID()<<endl;
            cout<<"UserName:"<<(*fromDBP)->getMemberName()<<endl;
            cout<<"Confirm To Modify? (y/n):";
            while(1){
                cin>>confirm;
                cin.clear();
                cin.ignore(100,'\n');
                if(!(confirm == 'y' || confirm == 'n')){
                    cout<<"Invalid Input!! Please re-enter:";
                    cin>>confirm;
                    cin.clear();
                    cin.ignore(100,'\n');
                }
            break;
            }
    
            if(confirm == 'y')
            {
            // copy MA to be modified to maToDB
                *maToDB = *fromDBP;
                toconfirm = true;
            }
            else
                toconfirm = false;
    
        if (toconfirm == true)
        {
            do{
            
                cout<<
                "1)\tMemberID"<<endl<<
                "2)\tUserName"<<endl<<
                "3)\tPassword"<<endl<<
                "4)\tRewards"<<endl<<
                "5)\tAdminStatus"<<endl;
        
                cout<<"Please Enter Choice:";
                cin>>count;
                cin.clear();
                cin.ignore(100,'\n');
        
                switch(count)
                {        
                   case 1:
                    {
                        cout<<"Please Enter New AccountID: ";
                        getline(cin, temp);
                        cout<<"Changes"<<(*fromDBP)->getMemberID()<<" --> "<<temp<<endl;
                        maToDB->setMemberID(temp);
                        modMID = true;
                        break;
                    }
                    case 2:
                    {
                        cout<<"Please Enter New UserName: ";
                        getline(cin,temp);
                        cout<<"Changes:"<<(*fromDBP)->getMemberName()<<" --> "<<temp<<endl;
                        maToDB->setMemberName(temp);
                        break;
                    }
                    case 3:
                     {
                        cout<<"Please Enter New Password: ";
                        getline(cin,temp);
                        cout<<"Changes:"<<(*fromDBP)->getMemberPassword()<<" --> "<<temp<<endl;
                         maToDB->setMemberPassword(temp);
                        break;
                    }
                    case 4:
                    {
                        cout<<"Enter New Rewards: ";
                        cin>>count;
                        cin.clear();
                        cin.ignore(100,'\n');

                        cout<<"Changes:"<<(*fromDBP)->getRewardPoints()<<" --> "<<count<<endl;
                        maToDB->setRewardPoints(count);
 
                        break;
                    }
                    case 5:
                    {
                        cout<<"Change Admin Status"<<endl;
                        cout<<"1)\t Member"<<endl;
                        cout<<"2)\t Admin"<<endl;
			
			cout << endl << "Enter Option : ";
                        cin>>count;
                        cin.clear();
                        cin.ignore(100,'\n');										
                
                        if(count == 1){
                            temp = "Member";
                        }
                        else{
                            temp = "Admin";
                        }
                        cout<<"Changes:"<<(*fromDBP)->getType()<<" --> "<<temp<<endl;
                        maToDB->setType(temp);
                        break;
                    }
                    default:
                    {
                        cout<<"Invalid Input!!"<<endl;
                        inputError = true;
                    }
                }
            }while(inputError);
        
            cout<<"Confirm and modify? (y/n):";
            while(1){
               cin>>confirm;
               cin.clear();
               cin.ignore(100,'\n');
                if(!(confirm == 'y' || confirm == 'n'))
                {
                    cout<<"Invalid input, Please re-enter:";
                    continue;
                }
                break;
            }
			
            // if memebrID is changed
            if(modMID)
            {
                checkP = fromDB.begin();
                while(checkP != fromDB.end())
                {
                    // check if new memeberID overwrites any other accounts, other than the one is being changed
                    if((*checkP)->getMemberID() == maToDB->getMemberID() && checkP != fromDBP)
                    {
                        conflicts = true;
                        break;
                    }
                    checkP++;
                }

                if(conflicts)
                {
                    cout << "Another account with the same MemebrID exists! Overwrite? (y/n)";
                    cin >> confirm;
                    cin.clear();
                    cin.ignore(100,'\n');
                }
            }   
        
            if(confirm == 'y' && conflicts)
            {
                // delete MA that will be overwritten
                toDB.push_back((*checkP));
                dbMemberAccount('d', toDB);
                // update MA that has changed MID
                temp = (*fromDBP)->getMemberID();
                dbUpdateMemberID(temp, maToDB);
            }
            else if(confirm == 'y')
            {
                toDB.push_back(maToDB);
                dbMemberAccount('u', toDB);
            }
            else
            {
                cout << "\nChanges not saved!" << endl;
            }
    
        }
        else
        {
             cout << "\nReturning to Main Menu... \n" << endl;
        }
    } 
}

void AdminAccount::deleteHotelReview(){
    
    vector<HotelReview> contentReview;
    vector<HotelReview> updateDb;
    vector<HotelReview>::iterator r;
    int count, counter;
    char confirm;
    string temp;
    
    dbHotelReview('s', contentReview);
    
    
    
        count=0;
        r=contentReview.begin();
        
        cout<<"\tReviewID\tCustomerID\tHotelID\tLocation\tValueForMoney\tcomfort\tservice\taverage\tcomments"<<endl;
        while(r!=contentReview.end()){
            cout<<"["<<count+1<<"]"<<(*r).getReviewId()<<","<<(*r).getCustomerId()<<","<<(*r).getHotelId()<<","<<(*r).getLocationRating()<<","<<(*r).getValueForMoneyRating()<<","<<(*r).getComfortRating()<<","<<(*r).getServiceRating()<<","<<(*r).getAverageRating()<<","<<(*r).getComments()<<endl;
            
            count++;
            r++;
        }
        
        do
        {
            cout<<"Which review to delete? (0 to return):";
            cin>>counter;
            cin.clear();
            cin.ignore(100, '\n');
            
            if (counter > count  || counter <0)
            {
                cout << "Invalid Entry! Please try again" << endl;
            }
	} while (counter > count  || counter <0);
        
        if (counter != 0)
        {
            r=contentReview.begin();
            r+=counter-1;
        
            updateDb.push_back((*r));
        
            cout<<"\n----------------------------------------\n";
            cout<< "Deleting Entry" << endl;
            cout<<"["<<counter<<"]"<<(*r).getReviewId()<<","<<(*r).getCustomerId()<<","<<(*r).getHotelId()<<","<<(*r).getLocationRating()<<","<<(*r).getValueForMoneyRating()<<","<<(*r).getComfortRating()<<","<<(*r).getServiceRating()<<","<<(*r).getAverageRating()<<","<<(*r).getComments()<<endl;
            cout<<"Confirm to delete? (y/n):";
            while(1){
                cin>>confirm;
                cin.clear();
                cin.ignore(100, '\n');
                if(!(confirm == 'y' || confirm == 'n')){
                    cout<<"Character invalid please re-enter:";
                    continue;
                }
                break;
            }
        
            if(confirm == 'y'){
                
                dbHotelReview('d', updateDb);
                cout << "Review Successfully Deleted" << endl;
            }
            else{
                updateDb.clear();
            }
        }
        
        cout << "Returning to Main Menu...\n" << endl;
    
}

void AdminAccount::allowHotelReview(){
    
    vector<MemberAccount*> memV;
    vector<MemberAccount*>::iterator p;
    vector<string> req, grant;
    vector<string>::iterator r;
    
    dbMemberAccount('s', memV);
    
    string memberID;
    int count=0, counter;
    bool found = false;
    char confirm;
    
			cout<<"Enter MemberID:";
			getline(cin, memberID);

			p=memV.begin();

			while(p!=memV.end()){

					if((*p)->getMemberID() == memberID){
                                            found = true;
							break;
					}
					p++;
			}
                    if (found)
                    {
			req = (*p)->getReviewRequestedFor();
			grant = (*p)->getReviewGrantedFor();
			
			if((*p)->getReviewRequestedFor().empty())
			{
				cout << "User has not requested any reviews!\n";
				return;
			}

			cout<<"Review Request"<<endl;

			r=req.begin();
			while(r!=req.end()){

					cout<<"["<<count<<"]"<<(*r)<<",";
					count++;
					r++;
			}

                        do{
                            cout<<"\nWhich one to grant?:";
                            cin>>counter;
                            cin.clear();
                            cin.ignore(100, '\n');
                            
                            if (counter > count-1 || counter < 0)
                            {
                                cout << "Invalid Option! Please try again" << endl;
                            }
                        } while (counter > count-1 || counter < 0);
			r=req.begin();
			r+=counter;

			grant.push_back((*r));
			req.erase(r);

			(*p)->setReviewGrantedFor(grant);
			(*p)->setReviewRequestedFor(req);

			dbMemberAccount('u', memV);
                    }
                    else
                    {
                        cout << "Member ID not found" << endl;
                        cout << "Returning to Main Menu" << endl;
                    }
}

void AdminAccount::viewSummary(){
    
    vector<HotelSummary> aReviews;
    vector<HotelSummary>::iterator p;
    
    dbGetHotelSummary(aReviews);
    cout<<"Summary of All Hotel Reviews\n";
    cout<<setfill('=')<<setw(40) << "" << setfill(' ');
		cout << setw(45) << right << "Rating\n"
				<< setw(10) << "Hotel ID"
				<< setw(30) << "Hotel Name"
				<< setw(10) << "Average" 
				<< setw(10) << "Location" 
				<< setw(10) << "Comfort"
				<< setw(10) << "Service"
				<< setw(17) << "Value For Money\n";
    p=aReviews.begin();
    while(p!=aReviews.end()){
        
			cout << setprecision(2) 
					<< setw(10) << (*p).hotelID
					<< setw(30) << (*p).name
					<< setw(10) << (*p).averageRating
					<< setw(10) << (*p).locationRating 
					<< setw(10) << (*p).comfortRating
					<< setw(10) << (*p).serviceRating 
					<< setw(17) << (*p).valueForMoneyRating 
					<< endl;
        
			p++;
    }    
}

ostream& operator<<(ostream& out, AdminAccount& oa){
    
    out<<oa.getMemberID()<<"|"<<oa.getMemberName()<<"|"<<oa.getMemberPassword()<<"|"<<oa.getRewardPoints()<<"|"<<oa.getType()<<"|";
    
    if(oa.getAuthenticate() == true){
        
        out<<"ok"<<endl;
    }
    else{
        out<<"notOk"<<endl;
    }
    
    return out;
}

istream& operator>>(istream& in, AdminAccount& interupt){
    
    
    string id;
    string nme;
    string pass;
    string type;
    
    cout<<"Enter New UserID:";
    cin>>id;
    cin.clear();
    cin.ignore(100,'\n');
    
    cout<<"Enter Name:";
    getline(cin, nme);
    
    cout<<"Enter Password:";
    cin>>pass;
 		cin.clear();
		cin.ignore(100, '\n');   
    cout<<"Member/Admin:";
    while(1){
        cin.clear();
        cin>>type;
				cin.clear();
				cin.ignore(199, '\n');				
        if(!(type == "Member" || type == "Admin")){
            cin.clear();
            cin.ignore(100, '\n');
            cin>>type;
            continue;
        }
        break;
    }
    
    interupt.setMemberID(id);
    interupt.setMemberName(nme);
    interupt.setMemberPassword(pass);
    interupt.setRewardPoints(0);
    interupt.setType(type);
    interupt.setAuthenticate(false);
    
    return in;
}

bool AdminAccount::operator==(AdminAccount& right)
{
    
    AdminAccount left=*this;
    
    if(left.getMemberID() == right.getMemberID())
        return true;
    
    return false;
    
}